
#include "Record.h"
#include <iostream.h>


double Record :: GetDouble (int i) {
	return myData[i].GetDouble();
}

int Record :: GetInt (int i) {
	return myData[i].GetInt();
}

char *Record :: GetString (int i) {
	return myData[i].GetString();
}

void Record :: SetDouble (double in, int i) {
	mySize += myData[i].LoadDouble(in);
}

void Record :: SetInt (int in, int i) {
	mySize += myData[i].LoadInt(in);
}

void Record :: SetString (char *in, int i) {
	mySize += myData[i].LoadString(in);
}

void Record :: Print (Schema &mySchema) {


    	// loop through all of the attributes
        for (int i = 0; i < mySchema.numAtts; i++) {

            // print the attribute name
            cout << mySchema.myAtts[i].name << ": ";
            cout << "[";

            // here we determine the type, which given in the schema;
            // depending on the type we then print out the contents

            // first is integer
            if (mySchema.myAtts[i].myType == Int) {
                cout << myData[i].GetInt ();

                // then is a double
            } else if (mySchema.myAtts[i].myType == Double) {
                cout << myData[i].GetDouble ();

                // then is a character string
            } else if (mySchema.myAtts[i].myType == String) {
                char *myString = myData[i].GetString ();
                cout << myString;
		delete myString;
            }


            cout << "]";

            // print out a comma as needed to make things pretty
            if (i != mySchema.numAtts - 1) {
                cout << ", ";
            }
        }

    cout << "end \n";
}

Record :: Record () {

    mySize = sizeof (int);
    myData = 0;
    numAtts = 0;
};

Record :: ~Record () {

    delete [] myData;
    myData=0;

}

int Record :: FromBinary (char *here) {

    // remeber where we started sucking from
    char *orig = here;
    mySize = sizeof (int);

    // read in the size and allocate the memory
    memmove (&numAtts, here, sizeof(int));
    delete [] myData;
    myData = new Att[numAtts];

    // suck up all of the attributes
    here += sizeof (int);
    for (int i = 0; i < numAtts; i++) {
        here += myData[i].FromBinary (here);
        mySize += myData[i].GetLength ();
    } 

    // return the number of bytes written
    return (here - orig);	
}

int Record :: ToBinary (char *here) {

    // remeber where we started sucking from
    char *orig = here;

    // write out the size and allocate the memory
    memmove (here, &numAtts, sizeof(int));

    // write out all of the attributes
    here += sizeof (int);
    for (int i = 0; i < numAtts; i++) {
        here += myData[i].ToBinary (here);
    } 

    // return the number of bytes written
    return (here - orig);
}

int Record :: GetLength () {
    return mySize;
}

int Record :: SuckNextRecord (Schema &mySchema, FILE *textFile) {

    delete [] myData;
    mySize = sizeof (int);
    numAtts = mySchema.numAtts;
    myData = new Att[numAtts];

    // the value 1000 is a magic number telling us the biggest size of a line in the text file
    char *space = new char[1000];

    // loop through all of the attributes
    for (int i = 0; i < numAtts; i++) {

        // first we suck in the next attribute value
        int len = 0;
        while (1) {
            int nextChar = getc (textFile);
            if (nextChar == '|')
                break;
            else if (nextChar == EOF) {
                delete space;
                return 0;
            }

            space[len] = nextChar;
            len++;
        }

        // null terminate the string
        space[len] = 0;

        // then we convert the data to the correct binary representation
        if (mySchema.myAtts[i].myType == Int) {
            int myInt = atoi (space);
            myData[i].LoadInt (myInt);

        } else if (mySchema.myAtts[i].myType == Double) {
            // updated
            double myDouble = atof (space);
            myData[i].LoadDouble (myDouble);

        } else if (mySchema.myAtts[i].myType == String) {
            myData[i].LoadString (space);
        }

        mySize += myData[i].GetLength () + sizeof (int);
    }

    delete space;
    return 1;
}

void Record :: Consume (Record &fromMe) {
    delete [] myData;
    mySize = fromMe.mySize;
    myData = fromMe.myData;
    numAtts = fromMe.numAtts;
    fromMe.mySize = 0;
    fromMe.numAtts = 0;
    fromMe.myData = 0;
}

